using System.Web.Mvc;
using ExtendedMvc.Html;

namespace ExtendedMvc.Elements {
	public class Label<TModel> : LabelBase<Label<TModel>, TModel> where TModel : class {
		public Label(IModelViewHelper<TModel> helper, string memberName, string targetId = null, string id = null) : base(helper, memberName, targetId, id) { }
	}

	public abstract class LabelBase<T, TModel> : FormElement<T, TModel>
		where T : LabelBase<T, TModel>
		where TModel : class {
		private const string labelSuffix = "_Label";

		private string _targetId;
		private object _content;
		private string _format;
		private bool _required = false;
		private ModelMetadata _metadata;

		protected LabelBase(IModelViewHelper<TModel> helper, string memberName, string targetId = null, string id = null)
			: base(helper, HtmlTag.Label, memberName, (id ?? (targetId ?? memberName) + labelSuffix)) {
			_targetId = targetId ?? memberName;
			_metadata = helper.GetMetadataForProperty(memberName);
			if (_metadata != null) _required = _metadata.IsRequired;
		}

		public virtual T Text(object value) {
			_content = value;
			return (T)this;
		}

		public virtual T Format(string value) {
			_format = value;
			return (T)this;
		}

		protected virtual string FormatValue() {
			if (_content == null) return null;
			if (string.IsNullOrEmpty(_format)) return _content.ToString();
			var format = (_format.Contains("{0}") || _format.Contains("{0:")) ? _format : "{0:" + _format + "}";
			return string.Format(format, _content);
		}

		protected override bool UseNameAttribute { get { return false; } }

		protected override void SetId() {
			if (string.IsNullOrWhiteSpace(id)) base.Id(_targetId + labelSuffix);
			base.SetId();
		}

		protected override void Prepare() {
			SetAttribute(HtmlAttribute.For, _targetId);
			base.Prepare();
		}

		protected override void SetContent() {
			if (_content == null && _metadata != null && _metadata.DisplayName != null) _content = _metadata.DisplayName;
			if (_content == null) _content = memberName;
			Builder.InnerHtml = FormatValue();
			base.SetContent();
		}
	}
}
